package com.info.zhiduoduo.core.service.impl;

import com.baomidou.mybatisplus.mapper.Condition;
import com.google.common.collect.Lists;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.maker.MakerType;
import com.info.zhiduoduo.common.constants.partner.PartnerBrokerageType;
import com.info.zhiduoduo.common.constants.project.CalcAmountType;
import com.info.zhiduoduo.common.constants.project.ProjectType;
import com.info.zhiduoduo.common.exception.Asserts;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.utils.LogUtil;
import com.info.zhiduoduo.common.utils.NumberUtil;
import com.info.zhiduoduo.common.utils.RandomUtil;
import com.info.zhiduoduo.core.dto.taxer.TaxerInvoiceServiceChargeDto;
import com.info.zhiduoduo.core.service.CoreProjectService;
import com.info.zhiduoduo.core.service.CoreTaxerService;
import com.info.zhiduoduo.repository.dto.maker.StudioDetailDto;
import com.info.zhiduoduo.repository.dto.project.ProjectServiceChargeDto;
import com.info.zhiduoduo.repository.dto.project.ProjectTaxFeeDto;
import com.info.zhiduoduo.repository.dto.taxfee.TaxFeeMoneyDto;
import com.info.zhiduoduo.repository.entity.address.AddressTaxRate;
import com.info.zhiduoduo.repository.entity.company.Company;
import com.info.zhiduoduo.repository.entity.maker.MakerStudio;
import com.info.zhiduoduo.repository.entity.partner.PartnerBrokerage;
import com.info.zhiduoduo.repository.entity.taxer.TaxerInvoice;
import com.info.zhiduoduo.repository.entity.taxer.TaxerPayment;
import com.info.zhiduoduo.repository.entity.taxer.TaxerRate;
import com.info.zhiduoduo.repository.mapper.address.AddressTaxRateMapper;
import com.info.zhiduoduo.repository.mapper.maker.MakerStudioMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerBrokerageMapper;
import com.info.zhiduoduo.repository.mapper.taxer.TaxerInvoiceMapper;
import com.info.zhiduoduo.repository.mapper.taxer.TaxerPaymentMapper;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class CoreTaxerServiceImpl implements CoreTaxerService {

	@Autowired
	CoreProjectService coreProjectService;

	@Autowired
	MakerStudioMapper makerStudioMapper;
	@Autowired
	TaxerInvoiceMapper taxerInvoiceMapper;
	@Autowired
	TaxerPaymentMapper taxerPaymentMapper;
	@Autowired
	AddressTaxRateMapper addressTaxRateMapper;
	@Autowired
	PartnerBrokerageMapper partnerBrokerageMapper;

	@Deprecated
	@Override
	public TaxerInvoiceServiceChargeDto calcInoiceServiceCharge(int invoiceid) {

		TaxerInvoice invoice = new TaxerInvoice().selectById(invoiceid);
		if (invoice == null) return null;

		Integer userid = invoice.getUserid();
		StudioDetailDto studio = makerStudioMapper.getStudioDetail(userid);
		return calculateZddMakerTaxerInvoice(studio, invoice);
	}

	@Override
	public TaxerInvoiceServiceChargeDto calcInvoiceServiceChargeV2(int invoiceid) {
		TaxerInvoice invoice = new TaxerInvoice().selectById(invoiceid);
		Asserts.notNull(invoice, StatusMsg.StatusMsg_714);

		//获取创客
		Integer userid = invoice.getUserid();
		StudioDetailDto studio = makerStudioMapper.getStudioDetail(userid);
		Asserts.notNull(studio, StatusMsg.StatusMsg_201);
		Integer makerType = studio.getMakerType();
		Integer taxer = studio.getTaxer();

		if (NumberUtil.intIn(makerType, MakerType.INTELL, MakerType.CROWDSOURCE) && NumberUtil.equals(taxer, Constants.TRUE)) {
			return calculateZddMakerTaxerInvoice(studio, invoice);
		} else if (makerType == MakerType.TAXER) {
			return calculateTaxerInvoice(studio, invoice);
		}
		throw SmartException.of(StatusMsg.StatusMsg_201);
	}

	/**
	 * 计算 创客纯代理模式的开票服务费
	 *
	 * @return
	 */
	private TaxerInvoiceServiceChargeDto calculateZddMakerTaxerInvoice(StudioDetailDto studio, TaxerInvoice invoice) {
		int userid = studio.getUserid();
		int invoiceid = invoice.getInvoiceid();
		boolean isSpecialInvoice = invoice.getInvoiceType() == 2;
		BigDecimal amount = invoice.getAmount();
		BigDecimal totalCharge = BigDecimal.ZERO;
		//计算税费
		ProjectTaxFeeDto taxFeeDto = coreProjectService.calcStudioTaxFee(studio, invoiceid, ProjectType.TAXER, isSpecialInvoice, amount, CalcAmountType.CHECKED);
		if (taxFeeDto != null) {
			invoice.setTaxRate(taxFeeDto.getTaxRatio()).setTaxFee(taxFeeDto.getTaxFee());
			totalCharge = totalCharge.add(taxFeeDto.getTaxFee());
		}

		//计算服务费
		ProjectServiceChargeDto serviceChargeDto = coreProjectService.calcStudioServiceCharge(studio, studio.getBindcompid(), invoiceid, ProjectType.TAXER, isSpecialInvoice, amount,
				CalcAmountType.CHECKED);
		if (serviceChargeDto != null) {
			invoice.setPartnerBaseServiceRate(serviceChargeDto.getPartnerBaseServiceRatio())
					.setPartnerBaseServiceCharge(serviceChargeDto.getPartnerBaseServiceCharge())
					.setPartnerProjectServiceRate(serviceChargeDto.getPartnerProjectServiceRatio())
					.setPartnerProjectServiceCharge(serviceChargeDto.getPartnerProjectServiceCharge())
					.setServiceRate(serviceChargeDto.getBaseServiceRatio())
					.setServiceCharge(serviceChargeDto.getServiceCharge());
			totalCharge = totalCharge.add(serviceChargeDto.getServiceCharge());
		}

		//  用户实际总待付金额(合伙人项目服务费+税费)
		invoice.setTotalCharge(totalCharge);
		if (invoice.updateById()) {
			TaxerInvoiceServiceChargeDto chargeDto = new TaxerInvoiceServiceChargeDto();
			BeanUtils.copyProperties(invoice, chargeDto);
			TaxerPayment invoicePayment = taxerPaymentMapper.findInvoicePayment(userid, invoiceid);
			if (invoicePayment != null && invoicePayment.getState() == 1) {
				//存在支付记录了，且还没有支付的情况下更新金额
				new TaxerPayment().setAmount(invoice.getServiceCharge().add(invoice.getTaxFee())).update(Condition.create().eq("invoiceid", invoiceid));
			}

			return chargeDto;
		}
		return null;
	}

	private TaxerInvoiceServiceChargeDto calculateTaxerInvoice(StudioDetailDto studio, TaxerInvoice invoice) {
		int userid = studio.getUserid();
		Integer invoiceid = invoice.getInvoiceid();
		Integer openingLocation = studio.getOpeningLocation();
		if (null == openingLocation || 0 == openingLocation) {
			throw SmartException.of(StatusMsg.StatusMsg_201);
		}
		//获取城市档位
		AddressTaxRate addressTaxRate = new AddressTaxRate().selectOne(Condition.create().eq("addr_id", openingLocation));
		if (null == addressTaxRate) {
			throw SmartException.of(StatusMsg.StatusMsg_902);
		}
		//获取当前创客的费率
		TaxerRate taxerRate = new TaxerRate().selectOne(Condition.create().eq("userid", userid));
		if (null == taxerRate) {
			throw SmartException.of(StatusMsg.StatusMsg_232);
		}

		// 计算税费
		BigDecimal handMoneys = new BigDecimal(0);
		//---将查询改掉
		TaxFeeMoneyDto yearMoneys = addressTaxRateMapper.getYearMoneys(invoiceid, userid);
		//年度总金额(加上了本次)
		BigDecimal money = yearMoneys.getYearMoney().add(yearMoneys.getMoney());
		//获取费率
		BigDecimal tax = null;
		//判断年度总金额是否达标，如果达标按年度档位来算
		if (money.compareTo(new BigDecimal(addressTaxRate.getYearOne())) > 0) {
			//年度总开票金额
			BigDecimal yearMoney = yearMoneys.getYearMoney();
			//已交税款
			BigDecimal handMoney = yearMoneys.getHandMoney();
			//判断金额满足哪个区间
			//三种情况：1.年度大于75万并且小于等于150万，2.年度大于150万并且小于等于300万，3.年度大于300万并且小于500万
			if (money.compareTo(new BigDecimal(addressTaxRate.getYearTwo())) <= 0) {
				//获取费率
				tax = taxerRate.getGearThree();
				//判断有没有刚好跨档位
				if (yearMoney.compareTo(new BigDecimal(addressTaxRate.getYearOne())) <= 0 && money.compareTo(new BigDecimal(addressTaxRate.getYearOne())) > 0) {
					handMoneys = getArrears(money, handMoney, tax);
				} else {
					handMoneys = yearMoneys.getMoney().multiply(tax);
				}
			} else if (money.compareTo(new BigDecimal(addressTaxRate.getYearThree())) <= 0) {
				//获取费率
				tax = taxerRate.getGearFour();
				//判断有没有刚好跨档位
				if (yearMoney.compareTo(new BigDecimal(addressTaxRate.getYearTwo())) <= 0 && money.compareTo(new BigDecimal(addressTaxRate.getYearTwo())) > 0) {
					handMoneys = getArrears(money, handMoney, tax);
				} else {
					handMoneys = yearMoneys.getMoney().multiply(tax);
				}
			} else if (money.compareTo(new BigDecimal(addressTaxRate.getYearThree())) > 0) {
				//获取费率
				tax = taxerRate.getGearFive();
				//判断有没有刚好跨档位
				if (yearMoney.compareTo(new BigDecimal(addressTaxRate.getYearThree())) <= 0 && money.compareTo(new BigDecimal(addressTaxRate.getYearThree())) > 0) {
					handMoneys = getArrears(money, handMoney, tax);
				} else {
					handMoneys = yearMoneys.getMoney().multiply(tax);
				}
			} else {
				LogUtil.info(" 税费计算-金额有误！金额：" + money.toString());
				throw SmartException.of(StatusMsg.StatusMsg_199);
			}
		} else {
			TaxFeeMoneyDto quarterMoneys = addressTaxRateMapper.getquarterMoneys(invoiceid, userid);
			//季度总开票金额
			BigDecimal quarterMoney = quarterMoneys.getQuarterMoney();
			//季度总金额(加上了本次)
			money = quarterMoneys.getQuarterMoney().add(quarterMoneys.getMoney());
			//已交税款
			BigDecimal handMoney = quarterMoneys.getHandMoney();
			//这里肯定是季度的计算
			//判断季度的区间，两种情况：1.季度小于等于30万并且年度小于等于75万，2.季度大于30万并且年度小于等于75万
			if (money.compareTo(new BigDecimal(addressTaxRate.getQuarter())) <= 0) {
				//获取费率
				tax = taxerRate.getGearOne();
				//计算税费
				handMoneys = quarterMoneys.getMoney().multiply(tax);
			} else {
				//获取费率
				tax = taxerRate.getGearTwo();
				//判断有没有刚好跨档位
				if (quarterMoney.compareTo(new BigDecimal(addressTaxRate.getQuarter())) <= 0 && money.compareTo(new BigDecimal(addressTaxRate.getQuarter())) > 0) {
					handMoneys = getArrears(money, handMoney, tax);
				} else {
					handMoneys = quarterMoneys.getMoney().multiply(tax);
				}
			}
		}

		//所有合伙人方式的服务费佣金总费率。（合伙人方式的服务费佣金比例包含在 的税率里面）
		double partnerServiceRatio = 0;
		//所有合伙人的项目服务费佣金总费率。（项目服务费的佣金比例在 的税率的基础上再增加的）
		double partnerProjectServiceRatio = 0;
		// 只有创客开通了计算分佣的功能,才会确认项目的合伙人
		if (NumberUtil.equals(studio.getBrokerageComputeState(), Constants.TRUE)) {
			partnerServiceRatio = partnerBrokerageMapper.getTaxerInvoiceBrokerageList(invoiceid, PartnerBrokerageType.BASIC).stream().mapToDouble(PartnerBrokerage::getRatio).sum();
			partnerProjectServiceRatio = partnerBrokerageMapper.getTaxerInvoiceBrokerageList(invoiceid, PartnerBrokerageType.PROJECT).stream().mapToDouble(PartnerBrokerage::getRatio).sum();
		}

		// 基础服务费包含在税费中, 项目服务费需要另外算.
		BigDecimal amount = invoice.getAmount();
		BigDecimal partnerProjectServiceCharge = amount.multiply(BigDecimal.valueOf(partnerProjectServiceRatio));
		BigDecimal partnerBaseServiceCharge = amount.multiply(BigDecimal.valueOf(partnerServiceRatio));
		//  的实际支付服务费等于合伙人项目服务费. 合伙人基础服务费包含在税费中
		BigDecimal serviceCharge = partnerProjectServiceCharge;
		Double serviceRate = partnerProjectServiceRatio;
		BigDecimal totalCharge = handMoneys.add(serviceCharge);

		// 更新数据
		invoice.setPartnerBaseServiceRate(partnerServiceRatio)
				.setPartnerBaseServiceCharge(partnerBaseServiceCharge)
				.setPartnerProjectServiceRate(partnerProjectServiceRatio)
				.setPartnerProjectServiceCharge(partnerProjectServiceCharge)
				.setServiceRate(serviceRate)
				.setServiceCharge(serviceCharge)
				.setTaxRate(tax.doubleValue())
				.setTaxFee(handMoneys)
				.setTotalCharge(totalCharge)
				.updateById();
		TaxerInvoiceServiceChargeDto chargeDto = new TaxerInvoiceServiceChargeDto();
		BeanUtils.copyProperties(invoice, chargeDto);
		TaxerPayment invoicePayment = taxerPaymentMapper.findInvoicePayment(userid, invoiceid);
		if (invoicePayment != null && invoicePayment.getState() == 1) {
			//存在支付记录了，且还没有支付的情况下更新金额
			new TaxerPayment().setAmount(invoice.getServiceCharge().add(invoice.getTaxFee())).update(Condition.create().eq("invoiceid", invoiceid));
		}

		return chargeDto;
	}

	/**
	 * 获取需要补缴的金额
	 *
	 * @param totalAmount  项目总金额
	 * @param handedTaxFee 历史已缴纳的总税金
	 * @param taxRatio     最新的税率（按此税率补缴）
	 * @return
	 */
	private BigDecimal getArrears(BigDecimal totalAmount, BigDecimal handedTaxFee, BigDecimal taxRatio) {
		BigDecimal totalHighTaxFee = totalAmount.multiply(taxRatio);

		//应付欠款,补交金额
		BigDecimal arrears = BigDecimal.ZERO;
		if (totalHighTaxFee.compareTo(handedTaxFee) > 0) {
			//应付的税金大于实际已付的，需要补交
			arrears = totalHighTaxFee.subtract(handedTaxFee);
		}
		return arrears;
	}

	public List<TaxerInvoiceServiceChargeDto> testInvoiceServiceCharge(int userid, BigDecimal amount, int count) {
		List<TaxerInvoiceServiceChargeDto> list = Lists.newArrayList();
		MakerStudio studio = new MakerStudio().selectById(userid);
		Company company = new Company().selectById(64);
		for (int i = 0; i < count; i++) {
			TaxerInvoice invoice = new TaxerInvoice().setUserid(userid)
					.setUsername(studio.getUsername())
					.setCompanyid(company.getCompid())
					.setCompanyName(company.getCompname())
					.setAmount(amount)
					.setInvoiceType(1)
					.setState(1);
			invoice.insert();
			TaxerPayment payment = new TaxerPayment().setUserid(userid).setInvoiceid(invoice.getInvoiceid()).setPayno(RandomUtil.createRandomNo("TEST_", "")).setType(3).setState(1);
			payment.insert();
			invoice.setPayid(payment.getPayid()).updateById();
			TaxerInvoiceServiceChargeDto chargeDto = calcInvoiceServiceChargeV2(invoice.getInvoiceid());
			// 修改状态为已支付
			invoice.setState(2).setConfirmtime(new Date()).updateById();
			payment.setState(2).setConfirmtime(new Date()).updateById();
			list.add(chargeDto);
		}
		return list;
	}

	public void deleteQuarterTestData(int userid, int quarter) {
		taxerInvoiceMapper.deleteQuarterData(userid, quarter);
		taxerPaymentMapper.deleteQuarterData(userid, quarter);
	}

	public void deleteYearTestData(int userid) {
		taxerInvoiceMapper.deleteYearData(userid);
		taxerPaymentMapper.deleteYearData(userid);
	}
}
